use std::sync::Arc;

use anyhow::Result;
use futures_util::{future, StreamExt, TryStreamExt};
use log::info;
use tokio::net::{TcpListener, TcpStream};
use whisper_rs::WhisperContext;

mod domain;
mod settings;
mod transcriber;

use settings::Settings;
use transcriber::Transcriber;

async fn handle_connection<'a>(context: Arc<WhisperContext>, raw_stream: TcpStream) -> Result<()> {
    let ws_stream = tokio_tungstenite::accept_async(raw_stream).await?;

    let transcriber = context.as_ref().create_state()?;

    let (outgoing, incoming) = ws_stream.split();

    incoming.try_for_each(|msg| future::ok(())).await?;

    Ok(())
}

#[tokio::main]
async fn main() -> Result<()> {
    // env_logger::init();
    // let settings = Settings::new()?;
    // let whisper_context = Arc::new(settings.whisper.context()?);
    //
    // let listening_addr = settings.app.listening_addr();
    // let listener = TcpListener::bind(&listening_addr).await?;
    // info!("Listening on: {:?}", listening_addr);
    //
    // while let Ok((stream, _addr)) = listener.accept().await {
    //     let transcriber = Transcriber::new(&whisper_context)?;
    //     tokio::spawn(handle_connection(whisper_context.clone(), stream));
    // }

    use hound::{WavReader, WavSpec};

    let settings = Settings::new().unwrap();
    let whisper_context = settings.whisper.context().unwrap();
    let mut transcriber = Transcriber::new(&whisper_context).unwrap();

    let mut wav = WavReader::open("audio.wav").unwrap();
    let WavSpec {
        channels,
        sample_rate,
        bits_per_sample,
        ..
    } = wav.spec();
    assert_eq!(channels, 1);
    assert_eq!(sample_rate, 16000);
    assert_eq!(bits_per_sample, 16);

    let mut audio = whisper_rs::convert_integer_to_float_audio(
        &wav.samples::<i16>()
            .flat_map(|s| Ok::<i16, anyhow::Error>(s?))
            .collect::<Vec<_>>(),
    );

    loop {
        let pcm = audio.drain(0..usize::min(128, audio.len()));
        if pcm.len() == 0 {
            break;
        }
        let res = transcriber.try_inference(pcm.as_slice()).unwrap();
        if let Some(segments) = res {
            println!("{segments:?}");
        }
    }

    Ok(())
}
